package com.lee.boot.head.first.demo.redis.lua;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;

/**
 * @author: Lee
 * @Date: 2019/11/11 0011 22:16
 * @Description: redis执行lua脚本有两种方式，
 * 一种是直接将脚本写入并执行，执行完毕返回执行结果，
 * 还有一种是，将脚本缓存入redis并返回一个32位的sha1值，在需要执行这个脚本时，传入sha值和所需要的参数
 */
@Component
public class RedisWithLua {
    @Autowired
    RedisTemplate redisTemplate;

    public Object runLuaInRedis(String arg) {
        DefaultRedisScript<String> redisScript = new DefaultRedisScript<>();
        redisScript.setScriptText("return 'redis lua'");
        redisScript.setResultType(String.class);
        RedisSerializer stringSerializer = redisTemplate.getStringSerializer();
        // 脚本执行结果
        String execute = (String) redisTemplate.execute(redisScript, stringSerializer, stringSerializer, null);
        // 脚本的sha值
        String sha1 = redisScript.getSha1();
        // 使用sha执行脚本的方式，其实使用redisTemplate的execute方法也是会先去获取redisScript的sha1摘要，再请求redis，
        // 如果使用摘要执行报noScriptError异常的话再去使用脚本字符串去请求redis执行脚本
        Object o = redisTemplate.getConnectionFactory().getConnection().evalSha(sha1.getBytes(), ReturnType.VALUE, 0);
        return null;
    }


}
